"""
测试用例模块视图和API实现

作者: heruopu
© 2025 Heruopu. All rights reserved.
"""

from rest_framework import viewsets, filters, permissions, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from .models import TestCase, CASE_STATUSES
from .serializers import TestCaseSerializer, TestCaseCreateSerializer, TestCaseUpdateSerializer, TestCaseListSerializer

class TestCaseViewSet(viewsets.ModelViewSet):
    """测试用例视图集"""
    queryset = TestCase.objects.all().order_by('case_id')
    serializer_class = TestCaseSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['version', 'status', 'priority', 'test_method', 'module', 'is_automated']
    search_fields = ['case_id', 'title', 'description', 'steps', 'expected_result']
    ordering_fields = ['case_id', 'created_at', 'updated_at', 'priority', 'status']
    permission_classes = [permissions.AllowAny]
    
    def get_serializer_class(self):
        """根据操作选择合适的序列化器"""
        if self.action == 'create':
            return TestCaseCreateSerializer
        elif self.action in ['update', 'partial_update']:
            return TestCaseUpdateSerializer
        elif self.action == 'list':
            return TestCaseListSerializer
        return TestCaseSerializer
    
    @action(detail=False, methods=['get'], url_path='case-statuses')
    def case_statuses(self, request):
        """获取用例状态列表"""
        return Response(dict(CASE_STATUSES))
    
    @action(detail=True, methods=['post'], url_path='review')
    def review(self, request, pk=None):
        """评审用例"""
        test_case = self.get_object()
        if test_case.status == 'reviewed':
            return Response({'status': 'error', 'message': '用例已评审'}, status=status.HTTP_400_BAD_REQUEST)
        
        reviewed_by = request.data.get('reviewed_by', '')
        is_approved = request.data.get('is_approved', True)
        
        if is_approved:
            test_case.status = 'reviewed'
            test_case.reviewed_by = reviewed_by
            from django.utils import timezone
            test_case.reviewed_at = timezone.now()
            test_case.save()
            return Response({'status': 'success', 'message': '用例评审通过'})
        else:
            test_case.status = 'rejected'
            test_case.reviewed_by = reviewed_by
            test_case.save()
            return Response({'status': 'success', 'message': '用例评审驳回'})
    
    @action(detail=True, methods=['post'], url_path='restore')
    def restore(self, request, pk=None):
        """恢复用例到草稿状态"""
        test_case = self.get_object()
        if test_case.status not in ['reviewed', 'rejected']:
            return Response({'status': 'error', 'message': '只有已评审或已驳回的用例才能恢复'}, status=status.HTTP_400_BAD_REQUEST)
        
        test_case.status = 'draft'
        test_case.reviewed_by = None
        test_case.reviewed_at = None
        test_case.save()
        return Response({'status': 'success', 'message': '用例已恢复到草稿状态'})
    
    @action(detail=False, methods=['post'], url_path='batch-delete')
    def batch_delete(self, request):
        """批量删除用例"""
        ids = request.data.get('ids', [])
        if not ids:
            return Response({'status': 'error', 'message': '请选择要删除的用例'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 只允许删除草稿状态的用例
        cases = TestCase.objects.filter(id__in=ids)
        valid_cases = cases.filter(status='draft')
        invalid_count = cases.count() - valid_cases.count()
        
        if invalid_count > 0:
            return Response({'status': 'error', 'message': f'有{invalid_count}个用例不是草稿状态，不能删除'}, status=status.HTTP_400_BAD_REQUEST)
        
        valid_cases.delete()
        return Response({'status': 'success', 'message': f'已删除{valid_cases.count()}个用例'})

# 创建API路由
from django.urls import path, include
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'test-cases', TestCaseViewSet)

urlpatterns = [
    path('', include(router.urls)),
]
